package mobilesmil.activity.composer;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

import mobilesmil.activity.R;
import mobilesmil.data.SmilResource;
import mobilesmil.utils.FormValidationUtils;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
/**
 * Provides form for editing the content of a text file and saving it to the SD card.
 * @author Ryan Ware
 *
 */
public class EditTextResourceActivity extends Activity {
	
	private Button mBtnTextSave;
	private Button mBtnTextCancel;
	private EditText mEditTextContent;
	private EditText mEditTextSource;
	
	private static String mDialogExceptionMessage;
	
	private static final byte DIALOG_LOAD_EXCEPTION_ID = 0;
	private static final byte DIALOG_SAVE_EXCEPTION_ID = 1;
	private static final byte DIALOG_INVALID_FORM_ID = 2;
	
	@Override
    public void onCreate(Bundle savedInstanceState){
		 super.onCreate(savedInstanceState);
	     setContentView(R.layout.edit_text_resource_layout);
	     String newOrEdit = getIntent().getExtras().getString("newOrEdit");
	     String textFileName = getIntent().getExtras().getString("textFileName");
	     
	     mBtnTextSave = (Button)findViewById(R.id.btnTextSave);
	     mBtnTextCancel = (Button)findViewById(R.id.btnTextCancel);
	     mEditTextContent = (EditText)findViewById(R.id.editTextContent);
	     mEditTextSource = (EditText)findViewById(R.id.editTextSource);
	     
	     if(newOrEdit.equals("edit") && textFileName != null)
	     { // editing an existing text file
	    	 mEditTextSource.setText(textFileName);
	    	 mEditTextSource.setEnabled(false);
	    	 try {
	    		 mEditTextContent.setText(getTextFromFile());
	    	 } catch (Exception e) {
	    		 mDialogExceptionMessage = "Unable to load text file.";
	    		 showDialog(DIALOG_LOAD_EXCEPTION_ID);
	    	 }
	     }
	     
	     mBtnTextSave.setOnClickListener(new View.OnClickListener(){
	 		@Override
			public void onClick(View view) {
				String newSource = mEditTextSource.getText().toString();
				if(fieldsAreValid())
				{
					if(!newSource.endsWith(".txt")) { // append ".txt" to file name
						mEditTextSource.setText(newSource + ".txt");
					}
					try {
						saveTextToFile(); // save file
					} catch (Exception e) { // display exceptino dialog to user
						mDialogExceptionMessage = "Unable to save text file.";
						showDialog(DIALOG_SAVE_EXCEPTION_ID);
					}
					getIntent().putExtra("newTextSource", mEditTextSource.getText().toString());
					setResult(RESULT_OK, getIntent()); // pass new text file name back to ResourcePropsFormActivity
					finish();
				}
				else {
					showDialog(DIALOG_INVALID_FORM_ID); // invalid user input field
				}
			};
		 });
	     
	     mBtnTextCancel.setOnClickListener(new View.OnClickListener(){
		 		@Override
				public void onClick(View view) {
					finish();
				};
			 });
	}
	
	/**
	 * Ensures user input fields contain valid values.
	 * @return true if all user input fields are valid, false if any are not
	 */
	private boolean fieldsAreValid() {
		String fileName = mEditTextSource.getText().toString();
		
		if(fileName.length() == 0) // must have a file name
			return false;
		
		for(char invalidChar : FormValidationUtils.INVALID_FILENAME_CHARS)
		{
			if(fileName.indexOf(invalidChar) >= 0) // value contains invalidChar
				return false;
		}
		
		return true;
	}
	
	@Override
	protected Dialog onCreateDialog(int id) {
	    AlertDialog dialog = new AlertDialog.Builder(this).create();
        dialog.setTitle(ComposerActivity.DIALOG_EXCEPTION_TITLE);
        dialog.setMessage(mDialogExceptionMessage);
        
	    switch(id)
	    {
		    case DIALOG_LOAD_EXCEPTION_ID: // text file contents could not be loaded
		        dialog.setButton("OK", new DialogInterface.OnClickListener() {
		          public void onClick(DialogInterface dialog, int which) {
		        	  setResult(RESULT_CANCELED);
		        	  finish();
		          } });
		        break;
		    
		    case DIALOG_SAVE_EXCEPTION_ID: // new text file could not be saved
		    	 dialog.setButton("OK", new DialogInterface.OnClickListener() {
			          public void onClick(DialogInterface dialog, int which) {
			            return;
			          } }); 
		    	 break;
		    	 
		    case DIALOG_INVALID_FORM_ID: // a user input field is invalid
		    	dialog = FormValidationUtils.createInvalidFormDialog(this);
		    	dialog.setTitle("Please enter a valid file name.");
		    	break;
	    }
	    return dialog;
	}
	
	/**
	 * Saves new text file to SD card.
	 * @throws Exception if text file could not be written to the SD card
	 */
	public void saveTextToFile() throws Exception {
		File root = Environment.getExternalStorageDirectory();
		File file = new File(root, mEditTextSource.getText().toString());
		file.createNewFile();
		
		FileWriter fileWriter = new FileWriter(file);
        BufferedWriter out = new BufferedWriter(fileWriter);
		try {
			out.write( mEditTextContent.getText().toString() );
		}
		finally {
			out.close();
		}
	}
	
	/**
	 * Reads text from given text file and returns as {@link String}.
	 * @return {@link String} text contents of file
	 * @throws Exception if file could not be read
	 */
	private String getTextFromFile() throws Exception {
		File root = Environment.getExternalStorageDirectory();
		File file = new File(root, mEditTextSource.getText().toString());
		StringBuilder contents = new StringBuilder();
	    
		BufferedReader input =  new BufferedReader(new FileReader(file));
		try {
			String line = null;
			while ((line = input.readLine()) != null)
			{ // read contents line by line
				contents.append(line);
				contents.append(System.getProperty("line.separator"));
			}
		}
		finally {
			input.close();
		}
		return contents.toString();
	}
}
